#include "Material.h"
#include "..\base\Engine.h"
#include "..\utils\Log.h"

namespace ds {

Material::Material(const char* name) : Asset(name) {	
	ZeroMemory( &m_D3DMaterial,sizeof( D3DMATERIAL9 ) );
	clear();	
}

Material::Material(const char* name,const char* textureName) : Asset(name) {
	LOGC(logINFO,"Material") << "creating material " << name << " with texture " << textureName;
	clear();
	TextureEntry te;
	te.sampler = 0;
	te.used = true;
	te.textureHandle = gEngine->getResourceManager().findByName(textureName,RS_TEXTURE);
	m_Entries[te.sampler] = te;
	m_UseLight = true;
	m_Alpha = false;	
	m_UseTextures = true;
}

Material::Material(const char* name,const ResourceHandle& textureHandle) : Asset(name) {
	LOGC(logINFO,"Material") << "creating material " << name << " with textureHandle";
	clear();
	TextureEntry te;
	te.sampler = 0;
	te.used = true;
	te.textureHandle = textureHandle;
	m_Entries[te.sampler] = te;
	m_UseLight = true;
	m_Alpha = false;
	m_UseTextures = true;
}

void Material::clear() {
	ZeroMemory( &m_D3DMaterial,sizeof( D3DMATERIAL9 ) );
	Set(WHITE);
	m_UseLight = false;
	m_Alpha = false;
	m_UseTextures = false;
	for ( int i = 0; i < 5; ++i ) {
		TextureEntry te;
		te.used = false;
		m_Entries[i] = te;
	}
}

Material::~Material() {
	LOGC(logINFO,"Material") << "Removing material " << getName();	
}

void Material::Use() {
	gEngine->getDevice()->SetMaterial(&m_D3DMaterial);
	
}

void Material::Set(const Color &color) {
	m_D3DMaterial.Diffuse = color;
	m_D3DMaterial.Ambient = color;
	m_D3DMaterial.Specular = color;
	m_D3DMaterial.Emissive = BLACK;
	m_D3DMaterial.Power = 1.0f;
}

void Material::SetAmbient(const Color &color) {
	m_D3DMaterial.Ambient = color;
}

void Material::SetDiffuse(const Color &color) {
	m_D3DMaterial.Diffuse = color;
}

void Material::SetSpecular(const Color &color, const float power) {
	m_D3DMaterial.Specular = color;
	m_D3DMaterial.Power = power;
}

void Material::SetEmissive(const Color &color) {
	m_D3DMaterial.Emissive = color;
}

void Material::applyTextures() {
	IDirect3DDevice9 * pDevice = gEngine->getDevice();
	for ( size_t i = 0; i < 5; ++i ) {
		if ( m_Entries[i].used ) {
			Texture* tr = gEngine->getResourceManager().getTexture(m_Entries[i].textureHandle);
			assert(tr != 0);
			HR(pDevice->SetTexture( m_Entries[i].sampler, tr->texture));	
		}
	}
}

void Material::replaceTexture(int index,ResourceHandle handle) {
	for ( size_t i = 0; i < 5; ++i ) {
		TextureEntry* te = &m_Entries[index];
		if ( te->sampler == index && te->used ) {
			LOGC(logINFO,"Material") << "found sampler - replacing handle";
			te->textureHandle = handle;
		}
	}
}

Texture* Material::getTexture(int sampler) {
	return gEngine->getResourceManager().getTexture(m_Entries[sampler].textureHandle);			
}

bool Material::hasTextures() {
	return m_UseTextures;
}
/*
void Material::addShader(Shader* shader) {
	m_Shaders.push_back(shader);
}

const bool Material::hasShaders() const {
	if ( m_Shaders.size() > 0 ) {
		return true;
	}
	return false;
}

const int Material::getShaderCounter() const {
	return m_Shaders.size();
}

Shader* Material::getShader(int index) {
	return m_Shaders[index];
}

Shader* Material::getShader(const char* name) {
	IdString hash = string::murmur_hash(name);
	for ( size_t i = 0; i < m_Shaders.size();++i) {
		Shader* s = m_Shaders[i];
		if ( s->getHash() == hash ) {
			return s;
		}
	}
	return 0;
}
*/
};
